package common.db;

import cn.hutool.json.JSONArray;
import common.utils.LogUtil;
import common.utils.StringUtil;
import lombok.var;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

public class DataBase {
    String url;
    String user;
    String password;

    public DataBase(String className, String url, String user, String password) throws ClassNotFoundException {
        SqlHelper.exceptionIfNoClass(className);
        this.url = url;
        this.user = user;
        this.password = password;
    }

    public Connection newConnection() throws SQLException {
        return SqlHelper.getConnection(url, user, password);
    }

    public Statement newStatement() throws SQLException {
        return newConnection().createStatement();
    }

    public void execute(String sql) throws SQLException {
        LogUtil.log("execute sql: \r\n" + sql);
        if (StringUtil.isEmpty(sql))
            return;
        var statement = newStatement();
        for (var subSql : sql.split(";\n"))
            statement.execute(subSql);
        SqlHelper.close(statement);
    }

    public ResultSet queryResult(String sql) throws SQLException {
        LogUtil.log("execute sql: \r\n" + sql);
        return newStatement().executeQuery(sql);
    }

    public JSONArray queryJArray(String sql) throws SQLException {
        return SqlHelper.getJArray(queryResult(sql));
    }

    public List<String> queryStrings(String sql) throws SQLException {
        return SqlHelper.getStrings(queryResult(sql));
    }

    public void debug() throws SQLException {
        SqlHelper.debug(newConnection());
    }

    String quote;

    public String getQuote() throws SQLException {
        if (StringUtil.isEmpty(quote))
            quote = SqlHelper.getQuote(newConnection());
        return quote;
    }

    public String addQuotes(String name) throws SQLException {
        return getQuote() + name + getQuote();
    }

    public String getDbName() throws SQLException {
        return SqlHelper.getDbName(newConnection());
    }

    public JSONArray getDbInfos() throws SQLException {
        return SqlHelper.getDbInfos(newConnection());
    }

    public JSONArray getTableInfos() throws SQLException {
        return queryJArray("select * from all_tables where OWNER='" + getDbName() + "'");
    }

    public List<String> getTableNames() throws SQLException {
        return queryStrings("select table_name from all_tables where OWNER='" + getDbName() + "'");
    }

    public boolean hasTable(String tableName) throws SQLException {
        return getTableNames().contains(tableName);
    }

    public List<ColumnInfo> getTableColumns(String tableName) throws SQLException {
        var result = queryResult("select * from " + tableName + " limit 0");
        var columns = SqlHelper.getColumns(result);
        SqlHelper.close(result);
        return columns;
    }

    public TableInfo getTableInfo(String tableName) throws SQLException {
        var table = new TableInfo();
        table.name = tableName;
        table.columns = getTableColumns(tableName);
        return table;
    }

    public void dropTable(String tableName) throws SQLException {
        execute("DROP TABLE IF EXISTS " + tableName + ";");
    }

}
